﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Collections;
using Doo.Scripts;

namespace Doo.WebUI
{
    public class ClientEventAttribute : Attribute
    {
        public string EventName { get; set; }

        public ClientEventAttribute(string name)
        {
            this.EventName = name;
        }
    }

    /// <summary>
    /// 库的基类
    /// 包括了客户端事件
    /// </summary>
    public class DooControl : ScriptControl, IUseScriptObject
    {
        const string _ScriptName = "Doo.WebUI.core.js";

        /// <summary>
        /// 客户端控件类别
        /// </summary>
        public virtual string ClientControlType { get { return ""; } }

        /// <summary>
        /// 客户端脚本
        /// </summary>
        public virtual string ScriptResourceName { get { return ""; } }

        /// <summary>
        /// 函数集
        /// </summary>
        public virtual string ScriptObjectID { get; set; }
        private Controls.ScriptObject _sobject;
        public Controls.ScriptObject ScriptObject
        {
            get { return _sobject ?? (string.IsNullOrEmpty(ScriptObjectID) ? null : FindControl(ScriptObjectID) as Controls.ScriptObject); }
            set { _sobject = value; }
        }

        ///客户端事件定义
        ///属性为events
        protected virtual Hashtable GetClientEventsHashtable()
        {
            if (!(this is Doo.Scripts.IClientEvent)) return null;

            var evts = this as Doo.Scripts.IClientEvent;

            //Find ClientEvents
            ClientEventsBase evtbase = this.GetType().GetProperty("ClientEvents").GetValue(evts, null) as ClientEventsBase;

            if (evtbase != null)
            {
                return evtbase.ToHashtable();
            }

            return null;
        }

        /// <summary>
        /// 返回脚本引用
        /// </summary>
        /// <returns></returns>
        protected override IEnumerable<ScriptReference> GetScriptReferences()
        {
            List<ScriptReference> list = new List<ScriptReference>(1);
            this.SetScriptReferences(list);
            list.Add(new ScriptReference(ScriptResourceName, this.GetType().Assembly.FullName));
            return list.AsEnumerable();
        }

        /// <summary>
        /// 设置脚本引用
        /// </summary>
        /// <param name="reference"></param>
        protected virtual void SetScriptReferences(List<ScriptReference> reference)
        {
            reference.Add(new ScriptReference(_ScriptName, this.GetType().Assembly.FullName));
        }

        /// <summary>
        /// 返回Descriptor
        /// </summary>
        /// <returns></returns>
        protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
        {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor(ClientControlType, this.ClientID);
            this.SetScriptDescriptor(descriptor);
            yield return descriptor;
        }

        protected virtual void SetScriptDescriptor(ScriptControlDescriptor descriptor)
        {
            descriptor.AddProperty("ctlid", ID);

            #region 设置脚本ID
            if (ScriptObject != null)
            {
                descriptor.AddProperty("scriptsid", ScriptObject.ClientID);
            }
            else
            {
                var ps = NamingContainer as IUseScriptObject;
                if (ps != null && ps.ScriptObject != null)
                {
                    descriptor.AddProperty("scriptsid", ps.ScriptObject.ClientID);
                }
                /*
                var ctl = Doo.Controls.ScriptObject.Current;
                if (ctl != null)
                {
                    descriptor.AddProperty("scriptsid", ctl.ClientID);
                }
                 */
            }
            #endregion

            #region 设置客户端事件

            Hashtable events = this.GetClientEventsHashtable();
            if (events != null && events.Count > 0)
            {
                Hashtable varevents = new Hashtable();
                foreach (string key in events.Keys)
                {
                    Doo.Scripts.ClientEvent evt = events[key] as Doo.Scripts.ClientEvent;
                    List<string> names = new List<string>();
                    if (evt == null || evt.Count == 0) continue;

                    foreach (var func in evt)
                    {
                        names.Add(func.GetClientReference());
                    }

                    varevents.Add(key, names);
                }
                descriptor.AddProperty("initevents", varevents);
            }

            #endregion
        }
    }

}